package com.jolink.omiis.commons.mongodb.api;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.bson.BsonDocument;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;

public class MongodbProcessor extends AbstractMongodbProcessor implements IMongodbProcessor {

	private static Logger logger = LoggerFactory.getLogger(MongodbProcessor.class);

	@Override
	public boolean delete(String collectionName, Bson filter) throws Exception {
		logger.info("执行mongodb删除操作......");
		long t1 = System.currentTimeMillis();
		MongoCollection<Document> mc = getMongoCollection(collectionName);
		if (mc == null) {
			throw new RuntimeException("获取mongodb-collection异常！");
		}

		DeleteResult deleteResult = mc.deleteOne(filter);
		long t2 = System.currentTimeMillis();
		logger.info("执行mongodb删除操作，受影响行数：" + deleteResult.getDeletedCount() + "，耗时：" + (t2 - t1) + "毫秒。");
		return Boolean.TRUE;
	}

	@Override
	public boolean insertOne(String collectionName, Map<String, Object> row) throws Exception {
		logger.info("执行mongodb插入操作......");
		long t1 = System.currentTimeMillis();
		MongoCollection<Document> mc = getMongoCollection(collectionName);
		if (mc == null) {
			throw new RuntimeException("获取mongodb-collection异常！");
		}
		if (logger.isDebugEnabled()) {
			logger.info("插入CollectionName=" + collectionName + "，Value=" + row);
		}
		try {
			Document doc = new Document(row);
			mc.insertOne(doc);
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
		long t2 = System.currentTimeMillis();
		logger.info("执行mongodb插入操作，耗时：" + (t2 - t1) + "毫秒。");
		return Boolean.TRUE;
	}

	@Override
	public boolean update(String collectionName, Map<String, Object> row, Bson filter) throws Exception {
		logger.info("执行mongodb更新操作......");
		long t1 = System.currentTimeMillis();

		try {
			MongoCollection<Document> mc = getMongoCollection(collectionName);
			Document document = new Document("$set", row);
			UpdateResult updateResult = mc.updateOne(filter, document);
			logger.info(updateResult.toString());
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			return Boolean.FALSE;
		}
		long t2 = System.currentTimeMillis();
		logger.info("执行mongodb更新操作，耗时：" + (t2 - t1) + "毫秒。");
		return Boolean.TRUE;
	}

	@Override
	public List<Map<String, Object>> find(String collectionName, Bson filter) throws Exception {
		logger.info("执行mongodb查询操作......");
		long t1 = System.currentTimeMillis();
		MongoCollection<Document> mc = getMongoCollection(collectionName);
		FindIterable<Document> findIterable = mc.find(filter);
		List<Map<String, Object>> resultList = new ArrayList<>();
		for (Iterator<Document> it = findIterable.iterator(); it.hasNext();) {
			Document document = it.next();
			Set<Entry<String, Object>> sets = document.entrySet();
			Map<String, Object> row = new HashMap<>();
			for (Iterator<Entry<String, Object>> it2 = document.entrySet().iterator(); it2.hasNext();) {
				Entry<String, Object> entry = it2.next();
				row.put(entry.getKey(), entry.getValue());
			}
			resultList.add(row);
		}
		long t2 = System.currentTimeMillis();
		logger.info("执行mongodb查询操作，耗时：" + (t2 - t1) + "毫秒。");
		return resultList;
	}

	@Override
	public boolean insertMany(String collectionName, List<Map<String, Object>> rows) throws Exception {
		logger.info("执行mongodb批量插入操作......");
		long t1 = System.currentTimeMillis();
		MongoCollection<Document> mc = getMongoCollection(collectionName);

		if (mc == null) {
			throw new RuntimeException("获取mongodb-collection异常！");
		}

		List<Document> documents = new ArrayList<>();
		for (int i = 0; i < rows.size(); i++) {
			Map<String, Object> row = rows.get(i);
			try {
				documents.add(new Document(row));
			} catch (Exception e) {
				throw new RuntimeException(e.getMessage(), e);
			}
		}
		mc.insertMany(documents);
		long t2 = System.currentTimeMillis();
		logger.info("执行mongodb批量插入操作，耗时：" + (t2 - t1) + "毫秒。");
		return false;
	}

	@Override
	public List<Map<String, Object>> find(String collectionName) throws Exception {
		return find(collectionName, new BsonDocument());
	}
}
